﻿#region using statements

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;

#endregion

namespace XNAGameEngine.Alarms
{
    /// <summary>
    /// Class to manage the alarms
    /// </summary>
    public sealed class AlarmSystem
    {
        #region local fields

        private readonly List<AlarmObject> _alarmsExpired;

        /// <summary>
        /// The list of ACTIVE alarms
        /// </summary>
        private readonly List<AlarmObject> _alarmsList;

        private readonly List<AlarmObject> _alarmsNew;

        /// <summary>
        /// The object containing this alarm system
        /// </summary>
        private IAlarmListener _parent;

        #endregion

        #region constructors

        /// <summary>
        /// Constructor sets the parent reference and initializes the alarms list
        /// </summary>
        /// <param name="parent">reference to the object which contains this alarm system</param>
        public AlarmSystem(object parent)
        {
            if (!(parent is IAlarmListener))
                throw new SystemException(
                    "object passed in does not implement IAlarmSystemcallbacks");

            _alarmsList = new List<AlarmObject>();
            _alarmsExpired = new List<AlarmObject>();
            _alarmsNew = new List<AlarmObject>();
        }

        #endregion

        #region local methods

        /// <summary>
        /// Add an alarm to the system. 
        /// </summary>
        /// <param name="alarm">the alarm to add</param>
        public void Add(AlarmObject alarm)
        {
            _alarmsNew.Add(alarm);
        }

        /// <summary>
        /// Update all of the alarms in the list
        /// </summary>
        /// <param name="gameTime">the updated game time</param>
        public void Update(GameTime gameTime)
        {
            //update the alarms
            foreach (AlarmObject alarm in _alarmsList)
            {
                //if the alarm update returns true then it has expired and remove from the list
                if (alarm.Update(gameTime))
                    _alarmsExpired.Add(alarm);
            }

            //remove all expired alarms
            foreach (AlarmObject alarm in _alarmsExpired)
            {
                _alarmsList.Remove(alarm);
            }

            //add all new alarms to the list to update
            foreach (AlarmObject alarm in _alarmsNew)
            {
                _alarmsList.Add(alarm);
            }

            _alarmsNew.Clear();
            _alarmsExpired.Clear();
        }

        /// <summary>
        /// Removes all alarms from the alarm system
        /// </summary>
        public void Cleanup()
        {
            _alarmsList.Clear();
        }

        #endregion
    }
}